﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using LedCenter.Utils;

namespace LedCenter.GUI
{
    public partial class ObjectItem : UserControl
    {
        bool allowResize = false;
        bool allowMove = false;
        bool isSelected = false;
        static int sIndex = 0;
        public bool Selected
        {
            get { return isSelected; }
            set { isSelected = value; }
        }
        public ObjectItem()
        {
            InitializeComponent();
            sIndex++;
            _objModel = new ObjectItemModel();
            _objModel.ID = sIndex;
            _objModel.Rect = this.ClientRectangle;
            //_objModel.Size = this.Size;
            _objModel.DataChanged += new ObjectItemModel.DataChangedHandler(_objModel_DataChanged);
            dataChanged = true;
        }

        public ObjectItem(Size resolution)
        {
            InitializeComponent();
            sIndex++;
            _objModel = new ObjectItemModel();
            _objModel.ID = sIndex;
            _objModel.Rect = this.ClientRectangle;
            _objModel.LedPixelSize = resolution;
            _objModel.DataChanged += new ObjectItemModel.DataChangedHandler(_objModel_DataChanged);
            dataChanged = true;
        }

        ObjectItemModel _objModel;
        public ObjectItemModel Model
        {
            get { return _objModel; }
        }

        void _objModel_DataChanged()
        {
            dataChanged = true;
            this.Location = _objModel.Rect.Location;
            this.Size = _objModel.Rect.Size;
            if (System.IO.File.Exists(_objModel.Path))
                this.BackgroundImage = Image.FromFile(_objModel.Path);
        }

        void updateModel()
        {
            _objModel.Rect = new Rectangle (this.Location, this.Size);
        }

        private void pbResize_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            allowResize = true;
            dataChanged = true;
            InvokeOnClick(this, null);
        }

        private void pbResize_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            allowResize = false;
            dataChanged = true;
        }

        private void pbResize_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (allowResize)
            {
                //this.Height = pbResize.Bottom + e.Y;
                int tHeight = pbResize.Bottom + e.Y;
                //this.Width = pbResize.Right + e.X;
                int twidth = pbResize.Right + e.X;

                if(_objModel.LedPixelSize.Width > 0)
                {
                    twidth = (int)((twidth + _objModel.LedPixelSize.Width - 1) / _objModel.LedPixelSize.Width) * _objModel.LedPixelSize.Width;
                }

                if (_objModel.LedPixelSize.Height > 0)
                {
                    tHeight = (int)((tHeight + _objModel.LedPixelSize.Height - 1) / _objModel.LedPixelSize.Height) * _objModel.LedPixelSize.Height;
                }
                this.Size = new System.Drawing.Size(twidth, tHeight);
                dataChanged = true;
                updateModel();
                this.Parent.Invalidate();
                this.Invalidate();
            }
        }

        private void pbMove_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            allowMove = true;
            this.BorderStyle = BorderStyle.FixedSingle;
            dataChanged = true;
        }

        private void pbMove_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            allowMove = false;
            this.BorderStyle = BorderStyle.None;
            dataChanged = true;
        }

        //Graphics _parentGraphic;
        private void pbMove_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            //Debug.Write(e.Location + " : ");
            //Debug.WriteLine(this.Parent.PointToClient(e.Location));
            if (allowMove)
            {
                Point newPoint = new Point(this.Location.X + e.Location.X,
                    this.Location.Y + e.Location.Y);
                //Rectangle newRect = new Rectangle(newPoint,Size);
                //if (_parentGraphic == null)
                //    _parentGraphic = this.Parent.CreateGraphics();
                Rectangle visibleRect = new Rectangle(/*this.Parent.Location.X + */this.Parent.Margin.Left,
                    /*this.Parent.Location.Y + */this.Parent.Margin.Top,
                    this.Parent.Width - this.Parent.Margin.Horizontal - this.Size.Width,// - this.Parent.Margin.Right ,
                    this.Parent.Height - this.Parent.Margin.Vertical - this.Size.Height);// - this.Parent.Margin.Bottom );

                //_parentGraphic.SetClip(visibleRect);

                //_parentGraphic.DrawRectangle(Pens.Black, visibleRect);
                //this.BorderStyle = BorderStyle.FixedSingle;
                //if (_parentGraphic.IsVisible(newPoint))
                if (newPoint.X < visibleRect.Location.X)
                {
                    newPoint.X = visibleRect.Location.X;
                }
                else if (newPoint.X > visibleRect.Right)
                {
                    newPoint.X = visibleRect.Right;
                }

                if (newPoint.Y < visibleRect.Location.Y)
                {
                    newPoint.Y = visibleRect.Location.Y;
                }
                else if (newPoint.Y > visibleRect.Bottom)
                {
                    newPoint.Y = visibleRect.Bottom;
                }
                dataChanged = true;
                this.Location = newPoint;
                updateModel();
                this.Parent.Invalidate();
                this.Invalidate();
            }
            else
            {
                this.BorderStyle = BorderStyle.None;
            }
            
        }

        private void pbMove_MouseEnter(object sender, EventArgs e)
        {
            this.pbMove.BackgroundImage = global::LedCenter.Properties.Resources.move;
            dataChanged = true;
        }

        private void pbMove_MouseLeave(object sender, EventArgs e)
        {
            this.pbMove.BackgroundImage = null;
            dataChanged = true;
            //pbMove.BackColor = Color.Transparent; 
        }

        private void ObjectItem_MouseDown(object sender, MouseEventArgs e)
        {
            dataChanged = true;
        }

        TriLedColorObjectRender render = new TriLedColorObjectRender();

        protected override void OnPaint(PaintEventArgs pe)
        {
            //if (dataChanged)
            {
                //base.OnPaint(e);
                if (isSelected)
                {
                    int penWidth = 1;
                    Graphics g = this.CreateGraphics();
                    Pen p = new Pen(Brushes.Black, penWidth);
                    Rectangle border = this.ClientRectangle;
                    border.X -= penWidth;
                    border.Y -= penWidth;
                    border.Width += penWidth;
                    border.Height += penWidth;
                    g.DrawRectangle(p, border);
                }

                int ledWidth = _objModel.LedPixelSize.Width > 0 ? Width / _objModel.LedPixelSize.Width : 0;
                int ledHeight = _objModel.LedPixelSize.Height > 0 ? Height / _objModel.LedPixelSize.Height : 0;

                Bitmap bm = new Bitmap(ledWidth, ledHeight, PixelFormat.Format24bppRgb);
                Graphics.FromImage(bm).Clear(Color.Red);
                render.Render(bm, this, pe.Graphics, _objModel.LedPixelSize, true);
                dataChanged = false;
            }
        }
        bool dataChanged = false;
        private void pbMove_DoubleClick(object sender, EventArgs e)
        {
            //propertyGrid.SelectedObject = objModel;
            //propertyGrid.Show();
        }

        private void ObjectItem_Resize(object sender, EventArgs e)
        {

        }
    }
    public enum ObjectType
    {
        TEXT,
        IMAGE,
        CLOCK,
        TEMP,
        PLAYLIST
    }

    /// <summary>
    // ObjectItemModel class to be displayed in the property grid
    /// </summary>
    /// 
    [DefaultPropertyAttribute("Name")]
    public class ObjectItemModel
    {
        private int _id;
        private ObjectType _type;
        private string _path;
        private Rectangle _rectangle;
        private Size _ledSize;

        public ObjectItemModel()
        {
            ID = 1;
            Type = ObjectType.IMAGE;
            Path = "";
            Rect = new Rectangle(0, 0, 160, 160);
            LedPixelSize = new Size(10, 10);
        }

        [CategoryAttribute("Settings"), DescriptionAttribute("ID of the object")]
        [ReadOnlyAttribute(true)]
        public int ID
        {
            get
            {
                return _id;
            }
            set
            {
                _id = value;
            }
        }

        [CategoryAttribute("Settings"), DescriptionAttribute("Type of the object")]
        public ObjectType Type
        {
            get
            {
                return _type;
            }
            set
            {
                _type = value;
            }
        }

        [Category("Settings")]
        [Description("Source file for images")]
        //[EditorAttribute(typeof(CustomFileNameEditor), typeof(CustomFileNameEditor))]
        [EditorAttribute(typeof(CustomFileNameEditor), typeof(System.Drawing.Design.UITypeEditor))]
        public string Path
        {
            get
            {
                return _path;
            }
            set
            {
                _path = value;
                PostDataChanged();
            }
        }

        [CategoryAttribute("Settings"), DescriptionAttribute("Rectangle of the object")]
        public Rectangle Rect
        {
            get
            {
                return _rectangle;
            }
            set
            {
                _rectangle = value;
                PostDataChanged();
            }
        }

        [CategoryAttribute("Settings"), DescriptionAttribute("Size of Led")]
        public Size LedPixelSize
        {
            get
            {
                return _ledSize;
            }
            set
            {
                _ledSize = value;
                PostDataChanged();
            }
        }

        /*
        [CategoryAttribute("Settings"), DescriptionAttribute("Location of the object")]
        public Size Size
        {
            get
            {
                return _size;
            }
            set
            {
                _size = value;
                PostDataChanged();
            }
        }
        */
        public delegate void DataChangedHandler();
        public event DataChangedHandler DataChanged;

        protected void PostDataChanged()
        {
            if (DataChanged != null)
            {
                DataChanged();
            }
        }

        class CustomFileNameEditor : System.Drawing.Design.UITypeEditor
        {
            public CustomFileNameEditor()
            {
            }

            private string _customFilter = "BMP files(*.bmp)| *.bmp | PNG files(*.png) | *.png | All files | *.*";

            [DefaultValue("BMP files(*.bmp)| *.bmp | PNG files(*.png) | *.png | All files | *.*")]
            public string CustomFilter
            {
                get { return _customFilter; }
                set { _customFilter = value; }
            }

            public override System.Drawing.Design.UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
            {
                // We'll show modal dialog (OpenFileDialog)
                return System.Drawing.Design.UITypeEditorEditStyle.Modal;
            }

            public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
            {
                using (OpenFileDialog dialog = new OpenFileDialog())
                {
                    dialog.Filter = this.CustomFilter;

                    if (dialog.ShowDialog() == DialogResult.OK)
                        value = dialog.FileName;
                }
                return value;
            }
        }
    }
}

